﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Business.CSDL.Type.Entity;
using Business.MSL.Condition;
using EDMDesigner.Controls.Mapping.Resources;
using EDMDesigner.Controls.Util;
using UIBusiness.MSL;

namespace EDMDesigner.Controls.Mapping
{
    public partial class TableMapping : UserControl, INotifyPropertyChanged
    {
        public TableMapping(EntityType entityType)
        {
            if (entityType == null)
                throw new ArgumentNullException();
            EntityType = entityType;
            InitializeComponent();
            tableNullValues.Collection = NullValue.GetValues(MappingResources.NullValueDelete);
        }

        private EntityType _entityType;
        public EntityType EntityType
        {
            get { return _entityType; }
            private set
            {
                _entityType = value;
                if (_entityType != null)
                {
                    _entityType.Mapping.ConditionsMapping.CollectionChanged +=
                        (sender, e) =>
                        {
                            columnConditionsGrid.ItemsSource = ColumnConditionsMapping;
                            propertyConditionsGrid.ItemsSource = PropertyConditionsMapping;
                        };
                    foreach (var propertyConditionMaping in PropertyConditionsMapping)
                        propertyConditionMaping.PropertyChanged += () => propertiesMappingControl.Mappings = PropertiesMapping;
                }
            }
        }

        private bool _tpc;
        public bool TPC
        {
            get { return _tpc; }
            set
            {
                _tpc = value;
                _propertiesMapping.TPC = value;
                propertiesMappingControl.TPC = value;
                complexPropertiesMappingControl.TPC = value;
            }
        }

        public bool HES { get; set; }

        private IEnumerable<Business.SSDL.EntityType.EntityType> _tables;
        public IEnumerable<Business.SSDL.EntityType.EntityType> Tables
        {
            get { return _tables; }
            set
            {
                _tables = value;
                tablesValues.Collection = Tables;
            }
        }

        private ComboBoxSelectedValueBindingWithNull<Business.SSDL.EntityType.EntityType> _tableComboBoxValue;
        public ComboBoxSelectedValueBindingWithNull<Business.SSDL.EntityType.EntityType> TableComboBoxValue
        {
            get
            {
                if (_tableComboBoxValue == null)
                    _tableComboBoxValue = new ComboBoxSelectedValueBindingWithNull<Business.SSDL.EntityType.EntityType>(null,
                        table =>
                        {
                            var oldTable = Table;
                            Table = table;
                            OnTableChanged(oldTable, table);
                        });
                return _tableComboBoxValue;
            }
        }

        private UIBusiness.MSL.PropertiesMapping _propertiesMapping;
        public UIBusiness.MSL.PropertiesMapping PropertiesMapping
        {
            get
            {
                if (_propertiesMapping == null)
                    _propertiesMapping = new UIBusiness.MSL.PropertiesMapping(EntityType, Table);
                return _propertiesMapping;
            }
        }

        private IEnumerable<ConditionMapping> ConditionsMapping
        {
            get { return EntityType.Mapping.ConditionsMapping.Where(ccm => ccm.Table == Table); }
        }
        public IEnumerable<Business.MSL.Condition.ColumnConditionMapping> ColumnConditionsMapping
        {
            get
            {
                return ConditionsMapping.OfType<Business.MSL.Condition.ColumnConditionMapping>();
            }
        }
        public bool ColumnConditionMappingVisible
        {
            get { return ColumnConditionsMapping.Any(); }
        }

        public IEnumerable<PropertyConditionMapping> PropertyConditionsMapping
        {
            get
            {
                return ConditionsMapping.OfType<PropertyConditionMapping>();
            }
        }
        public bool PropertyConditionMappingVisible
        {
            get { return HES && PropertyConditionsMapping.Any(); }
        }

        private Business.SSDL.EntityType.EntityType _table;
        public Business.SSDL.EntityType.EntityType Table
        {
            get { return _table; }
            set
            {
                var oldValue = _table;
                _table = value;
                OnPropertyChanged("Table");
                if (!HES)
                {
                    HES = EntityType.Mapping.ConditionsMapping.OfType<PropertyConditionMapping>().Any();
                    OnPropertyChanged("HES");
                }
            }
        }

        private void AddColumnConditionButton_Click(object sender, RoutedEventArgs e)
        {
            EntityType.Mapping.ConditionsMapping.Add(new ColumnConditionMapping { Table = Table });
            columnConditionsGrid.GetBindingExpression(Grid.VisibilityProperty).UpdateTarget();
        }

        private void AddPropertyConditionButton_Click(object sender, RoutedEventArgs e)
        {
            var propertyConditionMapping = new PropertyConditionMapping { Table = Table };
            propertyConditionMapping.PropertyChanged += () => propertiesMappingControl.Mappings = PropertiesMapping;
            EntityType.Mapping.ConditionsMapping.Add(propertyConditionMapping);
            propertyConditionsGrid.GetBindingExpression(Grid.VisibilityProperty).UpdateTarget();
        }

        public bool HasComplexMappings
        {
            get { return TPC ? EntityType.AllComplexProperties.Any() : EntityType.ComplexProperties.Any(); }
        }

        public UIBusiness.MSL.ComplexPropertiesMapping ComplexMappings
        {
            get { return new UIBusiness.MSL.ComplexPropertiesMapping(EntityType, EntityType.Mapping, Table) { TPC = TPC }; }
        }

        private void ColumnConditionMapping_ConditionDeleted(ColumnConditionMapping condition)
        {
            EntityType.Mapping.ConditionsMapping.Remove(condition);
            columnConditionsGrid.GetBindingExpression(Grid.VisibilityProperty).UpdateTarget();
        }

        private void PropertyConditionComboBox_Deleted(PropertyConditionMapping condition)
        {
            EntityType.Mapping.ConditionsMapping.Remove(condition);
            propertyConditionsGrid.GetBindingExpression(Grid.VisibilityProperty).UpdateTarget();
        }

        protected virtual void OnTableChanged(Business.SSDL.EntityType.EntityType oldTable, Business.SSDL.EntityType.EntityType newTable)
        {
            if (TableChanged != null)
                TableChanged(oldTable, newTable);
        }
        public event Action<Business.SSDL.EntityType.EntityType, Business.SSDL.EntityType.EntityType> TableChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}
